==Базовые возможности движка micro.fb (адаптированная версия для "Вереницы миров") ==

=Работа с предметами=

--Продажа предметов--

Продажа организуется весьма простым способом. На локации, где возможна торговля, в заголовке прописывается расширяющий тег класса <avs-seller>. Этот тег указывает движку, что на данной локации можно обменивать предметы на определённую валюту. В качестве валюты, как правило, выступают предметы типа [монета]. Вид валюты так же указывается в заголовке в тегах <avs-money: :avs-money>. Если необходимо, чтобы торговец интересовался только предметами определённого вида, необходимо перечислить через пробел идентификаторы видов этих предметов в тегах <avs-obj: :avs-obj>. Вот пример заголовка из готовой игры:

$lvar['заголовок']={277<avs-seller><avs-money:короны_розы:avs-money><avs-obj:шкура смола веер:avs-obj>}

Когда игрок достигнет сформированной таким образом локации, движок автоматически добавит пункт "Продать" в контекстное меню.

Квестовые предметы подлежат продаже, только когда явно заданы идентификаторы их видов.

--Тактическое использование предметов--

В игре разбросано множество предметов, которые можно использовать только в определённых ситуациях. Когда возникает ситуация, требующая использования конкретного предмета, в контекстном меню этого предмета появляется соответствующий пункт.

Реализовано это так:
	1. При щелчке на ссылке предмета запускается обработчик клика - локация 'onObjClick'.
	2. На этой локации по наличию в теле предмета одиночного тега '[useon:' определяется, является ли данный предмет тактически применимым или нет. Т.е. если тег есть, значит предмет можно использовать в определённых ситуациях.
	3. Далее из $maintxt производится выборка содержимого двойного тега <useof: :useof>. В этот тег должны быть включены идентификаторы видов предметов, которые можно использовать на локации. Идентификаторы видов помещаются в квадратные скобки. Пример:
		<useof:[пояс] [шлем] [антигравитатор]:useof>
	4. Если идентификатор вида обрабатываемого предмета соответствует одному из перечисленных в теге идентификаторов, в контекстное меню добавляется пункт "Воспользоваться"
	5. При выборе пункта "Воспользоваться" происходит обращение к локации 'menu.useon', с передачей уникального идентификатора предмета.
	6. На этой локации вновь происходит получение тела предмета и список его признаков (типов).
	7. Из тега [useon: ] извлекается число. Из имени текущей локации так же извлекается число. Оба числа суммируются, а сумма добавляется к строке 'page.'. Таким образом получено имя локации, на которую следует переместиться при использовании предмета.
	8. Осуществляется перемещение на локацию с полученым именем.

Тег <useof: :useof> лучше всего вписывать в заголовок.

Таким образом, чтобы согласовать применение предмета на месте, нужно в теле предмета, используя тег [useon: ] указать число, которое добавится к номеру текущего параграфа/локации (примеры: [useon:40] - на 40 параграфов вниз; [useon:-60] на 60 праграфов вверх). На локации, где предмет должен использоваться, необходимо в теге <useof::useof> указать идентификатор вида предмета, поместив его так же в квадратные скобки. Пример см. выше в п.3 реализации.

Так же в игре есть предметы, раскрывающие возможности локации. Как правило, в контекстном меню таких предметов уже появляется дополнительный пункт, который должен позволить использовать их, но при щелчке по нему, игрок видит сообщение "Нельзя использовать этот предмет здесь и сейчас". Однако попадая на соответствующую локацию, действие становится доступно игроку. Так, например, инфракрасные очки можно надевать только в темноте. Это реализовано следующим образом:
	1. При щелчке на ссылке предмета запускается обработчик клика - локация 'onObjClick'.
	2. На этой локации в зависимости от типа предмета создаётся пункт меню, который позволит игроку использовать предмет.
	3. При щелчке на этом пункте (Названия пункта могут отличаться, но в основном это "Надеть") происходит обращение к локации 'menu.use'.
	4. На этой локации из тела предмета выбирается содержимое тега <useoff::useoff>. (Для инфракрасных очков это 'avs-dark').
	5. Далее, если выбранное содержимое тега пусто, значит предмет можно использовать где угодно, и в итоге предмет таки пользуется игроком.
	6. Если же содержимое тега не пусто, в $maintxt производится поиск метки соответствующей выбранному содержимому. В $maintxt метка заключена в угловые скобки и т.о. скрыта от глаз игрока. Если указанная метка найдена, предмет пользуется, если нет - игроку выводится сообщение о невозможности здесь и сейчас применить предмет.

Таким образом, чтобы согласовать возможность использования предмета лишь в определённом месте, необходимо в теле предмета в теге [useoff: :useoff] указать метку условия использования предмета. Пример:
	[useoff:avs-dark:useoff]
И указать ту же метку, но в заголовке локации, поместив эту метку в угловые скобки:
	<avs-dark>

=Работа с локациями=

--События при первом посещении--

Это то, что должно случиться, когда игрок переходит на локацию (параграф), на которой он ещё не был. Событие должно произойти один раз, после чего не должно повторяться никогда. Поскольку движок заточен под книги-игры, и каждая локация по сути является параграфом (страницей) книги-игры, событий таких полно, и они действительно должны случаться раз за параграф. Например, герой заходит в комнату, а ему на голову падает ведро с лапшой, уменьшая его силу на единицу. Движок устроен таким образом, что при манипуляции с предметами и ссылками на той же самой локации, к ней будут происходить повторные обращения через команду goto. Если мы просто запишем событие в поле "выполнить при посещении", оно будет повторяться всякий раз при любом действии игрока, даже если он просто посмотрит информацию о предмете, лежащем в рюкзаке. Поэтому любое событие, которое должно выполниться всего один раз при посещении локации заключается в условие с переменной флагом:

if здесь_был[$curloc]=0:
	! событие при первом посещении локации.
end

Значение переменной-флага "здесь_был[$curloc]" автоматически изменится, менять его вручную не нужно. Теперь при последующих обращениях к локации, событие, заключённое в это условие, происходить не будет.

--Временные пременные--

Чтобы не хранить исходники описания локации в памяти, всякий раз при переходе на любую локацию уничтожается массив '$lvar'.

Иногда нужно сохранить значение до перехода на новую локацию, а потом уничтожить. Для этого используются переменные массива '$tvar'. Он уничтожается только при переходе по goto на абсолютно новую локацию.

Поскольку код на локации onNewLoc выполняется всегда после кода непосредственно посещённой локации, то если разместить присвоение значения ячейке массива $tvar на самой локации, при первом обращении к локации массив $tvar будет уничтожен. А если данные в нём нам нужны сразу при первом же обращении к локации? Существует простое решение этой проблемы. Уничтожение массива $tvar - самое первое, что делает алгоритм на локации onNewLoc. Уже потом идёт обработка исходников. Можно разместить возвращение значений ячйкам массива $tvar в исходнике локации. Тогда при первом обращении к локации $tvar уничтожается, потом происходит обработка исходников, где уже в свою очередь возвращаются новые значения массиву $tvar.

--Динамическое описание--

Создание локации под движок несколько отличается от привычного создания локации в QSP, если до сих пор вы пользовались полем "базовое описание" (основное описание). Описание локации/текст страницы присваивается временной переменной $lvar['исходник']. Так же, если есть необходимость, можно указать заголовок локации, внеся его значение в переменную $lvar['заголовок'].

При воспроизведении игры происходит следующее:
	1. Игрок переходит на локацию, где заголовок и описание возвращаются соответствующим переменным.
	2. Игра обращается к служебной локации 'onNewLoc', которая является локацией-обработчиком события перехода на новую локацию.
	3. На локации 'onNewLoc' происходит обращение к интерпретатору динамических текстов 'int.DIN', которому, в качестве аргумента, передаётся значение переменной $lvar['исходник'].
	4. Интерпретатор динамических текстов в полученном тексте производит поиск динамических конструкций, распознаёт их и преобразует текст в соответствии с инструкциями интерпретации этих конструкций.
	5. Поскольку интерпретатор является функцией, он возвращает полученный сформированный (итоговый) текст в виде значения локальной переменной $args['на экран'].
	6. Локация 'onNewLoc' запрашивает у других функций игры разные текстовые представления и передаёт их в качестве аргументов интерпретатору экрана 'int.screen'. Тот, являясь функцией, возвращает готовую html-таблицу, в которой размещаются описание локации, предметы и действия. Эта таблица и выводится на экран.

Чтобы облегчить написание динамического текста автору, были введены следующие динамические конструкции (упрощённые записи):

	[page=000]текст ссылки[/page]
		-	данная конструкция будет замещена гиперссылкой перехода на новую локацию. Поскольку имена всех локаций в игре состоят из строки 'page.' и числа, и это число считается номером локации, вместо нулей нужно указывать номер локации, на которую должен осуществляться переход. Пример:
			идти [page=392]прямо по улице[/page] или свернуть [page=256]направо в переулок[/page]?
		Данная строка преобразуется в:
			идти <a href="exec:time['goto']=1 & goto 'page.392'" title="переход на другую страницу" class="plain">прямо по улице</a> или свернуть <a href="exec:time['goto']=1 & goto 'page.256'" title="переход на другую страницу" class="plain">направо в переулок</a>?

	<a l:href="#n_000">текст ссылки</a>
		-	данная конструкция аналогична предыдущей. Её формат взят из исходников fb2-документов, что облегчает портирование текстов из fb2.
		Пример:
			идти <a l:href="#n_392">прямо по улице</a> или свернуть <a l:href="#n_256">направо в переулок</a>?
		Данная строка преобразуется в:
			идти <a href="exec:time['goto']=1 & goto 'page.392'" title="переход на другую страницу" class="plain">прямо по улице</a> или свернуть <a href="exec:time['goto']=1 & goto 'page.256'" title="переход на другую страницу" class="plain">направо в переулок</a>?

	[cur]текст ссылки|аргумент[/cur]
		-	данная конструкция преобразуется в гиперссылку возвращения на текущую локацию:
			<a href="exec:goto 'page.000','аргумент'" title="возврат на текущую локацию с указанием параметра сброс" class="plain">текст ссылки</a>
		Вместо 'page.000' автоматически подставляется имя текущей локации. Аргумент, передаваемый локации может позволить управлять состоянием локации при повторном к ней обращении. Так, например, можно ограничить число повторных обращений.

	[obj]ID_obj|текст ссылки[/obj]
		-	данная конструкция преобразуется в гиперссылку поднятия предмета с локации. Вместо ID_obj указывается точный идентификатор предмета, сброшенного на локации:
			<a href="exec:gosub 'add.obj','ID_obj'" title="добавление предмета" class="plain">текст ссылки</a>

	<DIN0: динамический код :0DIN>
		-	данная конструкция предназначена для размещения кусочков кода непосредственно в тексте описания локации. Когда интерпретатор динамических текстов сталкивается с такой конструкцией, текст, размещённый между двоеточиями, извлекается и направляется к выполнению как функция (используется функция $dyneval). Результат работы этой функции возвращается интерпретатору и заменяет собой конструкцию, из которой был получен. Так, например, в игре "Вереница миров" осуществлялся вывод текста в зависимости от наличия зарядов в бластере:
			<DIN1:$args['pos.bl']=$func('prv.obj.inBag','бластер')
			! проверяем заряды
			if $args['pos.bl']!"" and charge_array[arrpos('$id_array',$args['pos.bl'])]>0:
				$result='Можно попробовать <a href="exec:charge_array[<<arrpos("$id_array",$args["pos.bl"])>>]-=1 & time[''goto'']=1 & goto ''page.185''" class="plain">выжечь засов</a>, если, конечно, бластер заряжен. Иначе'
			else
				$result='<font color=#004400><i>Можно было бы  попробовать выжечь засов, вот только бластер разряжен</i></font>. Так что'
			end:1DIN> придётся [page=529]сидеть и ждать[/page], пока его светлость соизволит вспомнить о вас.
		Вместо нуля можно указывать любое число лишь бы число, указанное в открывающем теге, совпадало с числом в закрывающем теге.

	[pow]0[/pow]
		-	данная конструкция преобразуется в сообщение об изменении СИЛЫ. Вместо нуля следует указать положительное или отрицательно число. Если число положительное, будет выведена надпись: "СИЛА увеличивается на 0", если отрицательное "СИЛА уменьшается на 0". Пример:
			[pow]1[/pow]
		будет преобразовано в:
			<font color=#004400><i>СИЛА увеличивается на 1</i></font>

	[lovk]0[/lovk]
		-	данная конструкция преобразуется в сообщение об изменении ЛОВКОСТИ. Вместо нуля следует указать положительное или отрицательно число. Если число положительное, будет выведена надпись: "ЛОВКОСТЬ увеличивается на 0", если отрицательное "ЛОВКОСТЬ уменьшается на 0". Пример:
			[lovk]1[/lovk]
		будет преобразовано в:
			<font color=#004400><i>ЛОВКОСТЬ увеличивается на 1</i></font>

	[powernow]если сила больше нуля|если сила меньше нуля[/powernow]
		-	данная конструкция преобразуется в сообщение. В заисимости от значения переменной power['now'] будет выведено сообщение до вертикальной черты (power['now']<1) или после (power['now']>0). C помощью этой конструкции облегчается написание локаций, в которых значение переменной power['now'] изменяется безусловно, т.е. без участия игрока.

	[knew]short_word|если есть знание|если нет знания[/knew]
		-	 данная конструкция преобразуется в сообщение при наличии, или отсутствии, знания. Знания - это отдельный класс объектов игры. Они являют собой запись о наличии какой-либо информации у героя. Например, в игре "Вереница миров" герою рассказывают о том, как выбраться из темницы. При этом создаётся объект класса <knew> с определённым идентификатором вида. На локации, где герой оказался в темнице, присутствует данная конструкция. Интерпретатор распознаёт её и преобразует. Если герой "знает", как выбраться из темницы, выводится сообщение (как правило, в нём размещается ссылка перехода на новую локацию) - текстом ссылки является текст из конструкции до последнего разделителя. Если герой "не знает", как выбраться из темницы, выводится сообщение - текст в конструкции после последнего разделителя. Вместо short_word указывается идентификатор вида того знания, которое нужно на этой локации.

	[blaster]0|если бластер заряжен|если бластер разряжен|если бластер частично заряжен[/blaster]
		-	данная конструкция преобразуется в сообщение в зависимости от заряда бластера. Вместо нуля указывается число, до которого должен быть заряжен бластер. Если заряд бластера равен или больше этого числа, выводится первое сообщение (от первого разделителя до второго). Если заряд бластера равен нулю - второе (от второго разделителя до третьего). Если заряд бластера не равен нулю, но меньше указанного числа, выводится третье сообщение (после третьего разделителя).

	[usebl]0|000|текст ссылки[/usebl]
		-	данная конструкция преобразуется в гиперссылку перехода на новую локацию и уменьшения заряда бластера. Вместо нуля указывается число, соответствующее необходимому заряду бластера. Вместо '000' указывается номер страницы, на которую следует осуществить переход при наличии заряда. Как правило, используется в комбинации с [blaster][/blaster]. Пример:
			[blaster]1|[usebl]1|217|бластер[/usebl]|бластер[/blaster]
		При наличии в бластере заряда равного или больше единицы будет выведена строка '[usebl]1|217|бластер[/usebl]', которая, в свою очередь, сначала будет преобразована в гиперссылку:
			<a href="exec:gosub 'blast.charge',-1 & time['goto']=1 & goto 'page.217'" class="plain">бластер</a>
		Если же в бластере отсутствует заряд нужной величины, будет выведена строка 'бластер'.

	[upluck]текст сообщения[/upluck]
		-	данная конструкция преобразуется в сообщение-приглашение восстановить одно из чисел удачи. Пример:
			[upluck]УДАЧА: ВОССТАНОВИТЕ 1 ЦИФРУ.[/upluck]
		преобразуется в:
			<br><br><br><center><font color=#004400>УДАЧА: ВОССТАНОВИТЕ 1 ЦИФРУ.</font><br><font size=+1><b><a href="exec:gosub 'upluck.num','2'" title="upluck" class="plain">2</a>,   <a href="exec:gosub 'upluck.num','6'" title="upluck" class="plain">6</a></b></font></center><br><br>
		Вместо двойки и шестёрки, естественно могут быть другие числа (те, что находятся у игрока в списке чисел неудачи).

	[social]000|999[/social]
		-	данная конструкция преобразуется в гиперссылку-приглашение проверить своё обаяние. Вместо 000 указывается номер локации/страницы, на которую будет осуществлён переход в случае, если герой оказался достаточно обаятельным/убедительным. Вместо 999 указывается номер страницы в случае, если герой оказался недостаточно обаятельным/убедительным. Так будет выглядеть ссылка:
			<a href="exec:gosub 'social',000,999" class="plain">Проверить обаяние</a>

	[step]000|текст ссылки[/step]
		-	данная конструкция преобразуется в гиперссылку перехода на новую локацию. Вместо нулей указывается номер локации, на которую будет осуществлён переход, если это был первый мир, который герой посетил. Если же мир, который посетил герой не первый, будет осуществлено вычисление записанных номеров ворот и как итог номер страницы, на которую должен перейти герой. Так выглядит ссылка:
			<a href="exec:time['goto']=1 & goto 'page.000'" title="переход на другую страницу" class="plain">текст ссылки</a>

	[fast]000|999[/fast]
		-	данная конструкция аналогична конструкции [social][/social], только вместо обаяния проверяется ловкость.

	Пять подряд идущих пробелов заменяются на пять кодов спецсимвола '&nbsp;' - неразрывный пробел.

Достаточно сложно ввести упрощённые записи, похожие на BB-код, для всех случаев игры. В игре "Вереница миров" появились устойчивые конструкции, для повторяющихся случаев, но не использующие упрощённые записи.

	<DIN1:$result=$func('luck',$lvar['luck'],000,999):1DIN>
		-	данная конструкция преобразуется в гиперссылку-предложение проверить свою удачу. Вместо 000 указывается номер локации, на которую попадёт герой в случае удачи. Вместо 999 указывается номер локации, на которую попадёт герой в случае неудачи. Сама гиперссылка выглядит так:
			<a href="exec:goto $curloc,str(rand(1,6))">Проверить удачу</a>
		Когда игрок щёлкнет по ней, будет выброшено случайное число и игра вновь обратится к локации, передав ей это число в качестве аргумента. Тогда, если это число окажется в списке чисел удачи, выведется такая гиперссылка:
			Выпало число <font color=#880000>6</font>.
			<a href="exec:time['goto']=1 & goto 'page.000'" title="переход на другую страницу" class="plain">Вам повезло...</a>
		Если в списке чисел неудачи:
			Выпало число <font color=#880000>6</font>.
			<a href="exec:time['goto']=1 & goto 'page.999'" title="переход на другую страницу" class="plain">Вам не повезло...</a>

При создании динамического описания локации с использованием динамических конструкций следует соблюдать правила:
	1. Вложенность конструкций типа <DIN0: :0DIN> друг в друга ограничений не имеет, тем не менее число в тегах у вложенной конструкции должно отличаться от числа в тегах конструкции высшего порядка. Пример неправильной нумерации тегов:
		<DIN1:
			if a=1:
				$result='<DIN1:
					if b=2:
						$result="На берёзе созрело несколько яблок."
					else
						$result="На берёзе ещё нет яблок."
					end:1DIN>'
			else
				$result='<DIN2:
					if b=2:
						$result="На осине созрело несколько грибов."
					else
						$result="На осине ещё нет грибов."
					end:2DIN>'
			end
		:1DIN>
	Пример правильной нумерации тегов:
		<DIN1:
			if a=1:
				$result='<DIN2:
					if b=2:
						$result="На берёзе созрело несколько яблок."
					else
						$result="На берёзе ещё нет яблок."
					end:2DIN>'
			else
				$result='<DIN2:
					if b=2:
						$result="На осине созрело несколько грибов."
					else
						$result="На осине ещё нет грибов."
					end:2DIN>'
			end
		:1DIN>
	Пример желательной нумерации тегов (числа не повторяются):
		<DIN3:
			if a=1:
				$result='<DIN1:
					if b=2:
						$result="На берёзе созрело несколько яблок."
					else
						$result="На берёзе ещё нет яблок."
					end:1DIN>'
			else
				$result='<DIN2:
					if b=2:
						$result="На осине созрело несколько грибов."
					else
						$result="На осине ещё нет грибов."
					end:2DIN>'
			end
		:3DIN>
	2. Преобразование конструкций начинается с нижнего уровня. Т.е. Сначала преобразуются все вложенные конструкции, потом те, в которые они были вложены. В последнем примере сначала будет выполнено перобразование конструкций с тегами с числами 1 и 2, потом - с числом 3. Это позволяет комбинировать двойные и одинарные апострофы и фигурные скобки для возвращения результата с таким расчётом, что глубина вложений динамических конструкций может достигать десятков.
	3. Можно размещать теги конструкций друг в друге в любых комбинациях и на сколь угодно большую глубину вложений, но нельзя размещать однозначные теги друг в друге. Пример неправильного размещения тегов:
		[powernow]Вы сильно ударились плечом [powernow]и потеряли сознание|и, потеряв сознание от боли,[/powernow]|больше не очнулись[/powernow]
	Вот ещё пример:
		<a l:href="#n_569">сделать [page=23]шаг[/page] вперёд</a>
	4. Так же нельзя закрывать тег, если вложенный тег ещё не закрыт. Пример неправильного размещения тегов:
		[powernow]Кусты больно искололи вас своими колючками, но вам всё же удалось [page=99]выбраться на тропинку|[/powernow][/page]

--Свойства локаций. Заголовки--

Упрощение и автоматизация однотипных действий на локациях потребовали введения специальных меток (тегов) для локаций. Эти метки лучше всего размещать в заголовке локации для наглядности. Т.е. они помещаются в значение переменной $lvar['заголовок']. Метки могут иметь самое разное назначение: определять свойства локации, её тип, или разрешать или запрещать действия с предметами, и прочие. Вот список меток, используемых на локациях:

	<avs-death>
		-	локация проигрыша. Если в локации присутствует данная метка, на экран не выводятся ссылки переходов, а так же статусная информация и предметы. Данная метка автоматически добавляется к заголовку локации, когда здоровье героя падает до нуля.

	<avs-victory>
		-	локация победы. Если в локации присутствует данная метка, на экран не выводятся статусная информация и предметы. Данная метка означает, что игра пройдена до логического финала, соответствующего условной победе игрока.

	<avs-enemy>
		-	локация сражения. Если в локации присутствует данная метка, значит на этой локации можно сражаться. Движок автоматически генерирует ссылку перехода к бою.
	<avs-game:000|999:avs-game>
		-	локация игры. По наличию этой метки запускается мини-игра. В случае победы, герой перемещается на локацию 000, в случае поражения на локацию 999.

	<avs-dark>
		-	тёмная локация. Если в локации присутствует данная метка, значит некоторые действия недоступны для игрока, пока он не найдёт способ осветить локацию или видеть в темноте. В частности, только при наличии этого тега в игре "Вереница миров" игроку становится доступна возможность надеть инфракрасные очки "Ночное зрение".

	<useof: :useof>
		-	между тегами размещаются идентификаторы видов предметов, которые можно использовать на данной локации. Идентификаторы видов должны помещаться в квадратные скобки. Подробнее о теге, читайте выше в разделе "Тактическое использование предметов".

	<non-blaster>
		-	если в локации присутствует данная метка, значит использовать бластер на этой локации нельзя. Обыкновенно присутствует на локациях сражений, где противник не должен быть убит по сюжету игры.

	<avs-money: :avs-money>
		-	между тегами помещается идентификатор вида участвующей в торговле монеты. Так же метка свидетельствует о том, что данная локация является локацией торговли, обмена.

	<avs-obj: :avs-obj>
		-	между тегами помещаются идентификаторы видов предметов, которые могут быть проданы на данной локации. Идентификаторы видов должны включаться в квадратные скобки.

	<putlock: :putlock>
		-	между тегами размещаются идентификаторы типов предметов, которые нельзя сбрасывать на данной локации. Идентификаторы типов включаются в квадратные скобки.

	<lock.obj>
		-	если на локации присутствует данная метка, использование предметов на ней запрещено.

	<lock.put>
		-	запрещено сбрасывать предметы на локацию.